#include "i2c_sim.h"
#include "i2c_sim_port.h"




//发送起始信号
void i2c_sim_start(void)
{
	i2c_sim_port_setDIOMode(IS_IO_OUTPUT_MODE);
	i2c_sim_port_setDIOStatus(IS_IO_HIG_LEVEL);
	i2c_sim_port_setCLKStatus(IS_IO_HIG_LEVEL);
	i2c_sim_port_delay_nus(5);
	i2c_sim_port_setDIOStatus(IS_IO_LOW_LEVEL);
	i2c_sim_port_delay_nus(4);
	i2c_sim_port_setCLKStatus(IS_IO_LOW_LEVEL);
}


//发送停止信号
void i2c_sim_stop(void)
{
	i2c_sim_port_setDIOMode(IS_IO_OUTPUT_MODE);
	i2c_sim_port_setCLKStatus(IS_IO_LOW_LEVEL);
	i2c_sim_port_setDIOStatus(IS_IO_LOW_LEVEL);
	i2c_sim_port_setCLKStatus(IS_IO_HIG_LEVEL);
	i2c_sim_port_delay_nus(5);
	i2c_sim_port_setDIOStatus(IS_IO_HIG_LEVEL);
	i2c_sim_port_delay_nus(4);
	i2c_sim_port_setDIOStatus(IS_IO_LOW_LEVEL);
}


//等待ACK应答信号 0:接收应答成功	1:接收应答失败
unsigned char i2c_sim_wait_ack(void)
{
	uint8_t u8ErrCnt = 0;
	i2c_sim_port_setDIOStatus(IS_IO_HIG_LEVEL);
	i2c_sim_port_setCLKStatus(IS_IO_HIG_LEVEL);
	i2c_sim_port_setDIOMode(IS_IO_INPUT_MODE);
	while (i2c_sim_port_radDIOStatus() == 1)
	{
		u8ErrCnt++;
		if (u8ErrCnt > 250)
		{
			i2c_sim_stop();//发送停止信号
		   	return 1;
		}
	}
	i2c_sim_port_setCLKStatus(IS_IO_LOW_LEVEL);
	return 0;
}


//产生ACK应答信号
void i2c_sim_ack(void)
{
	i2c_sim_port_setCLKStatus(IS_IO_LOW_LEVEL);
	i2c_sim_port_setDIOMode(IS_IO_OUTPUT_MODE);	
	i2c_sim_port_setDIOStatus(IS_IO_HIG_LEVEL);
	i2c_sim_port_delay_nus(2);
	i2c_sim_port_setCLKStatus(IS_IO_LOW_LEVEL);
	i2c_sim_port_delay_nus(4);//>4us
	i2c_sim_port_setCLKStatus(IS_IO_LOW_LEVEL);
}


//产生NACK信号
void i2c_sim_nack(void)
{
	i2c_sim_port_setCLKStatus(IS_IO_LOW_LEVEL);
	i2c_sim_port_setDIOMode(IS_IO_OUTPUT_MODE);
	i2c_sim_port_setDIOStatus(IS_IO_HIG_LEVEL);
	i2c_sim_port_delay_nus(4);
	i2c_sim_port_setCLKStatus(IS_IO_HIG_LEVEL);
	i2c_sim_port_delay_nus(4);//>4us
	i2c_sim_port_setCLKStatus(IS_IO_LOW_LEVEL);
}


//发送一个字节
void i2c_sim_send_byte(unsigned char u8Data)
{
	unsigned char i;
	unsigned char u8Temp;
	i2c_sim_port_setDIOMode(IS_IO_OUTPUT_MODE);	
	i2c_sim_port_setDIOStatus(IS_IO_LOW_LEVEL);
	for (i = 0; i < 8; i++)
	{
		i2c_sim_port_delay_nus(2);
		#ifdef IIC_LSB//低位在前
		u8Temp = ((u8Data << (7 - i)) & 0x80);
		(u8Temp == 0x80) ? (i2c_sim_port_setDIOStatus(IS_IO_HIG_LEVEL)) : (i2c_sim_port_setDIOStatus(IS_IO_LOW_LEVEL));		
		#else//高位在前
		u8Temp = ((u8Data >> (7 - i)) & 0x01);
		(u8Temp == 0x01) ? (i2c_sim_port_setDIOStatus(IS_IO_HIG_LEVEL)) : (i2c_sim_port_setDIOStatus(IS_IO_LOW_LEVEL));
		#endif		
		i2c_sim_port_setCLKStatus(IS_IO_HIG_LEVEL);//时钟保持高电平
		i2c_sim_port_delay_nus(2);
		i2c_sim_port_setCLKStatus(IS_IO_LOW_LEVEL);//时钟拉低，才允许SDA变化
	} 
}


//读取一个字节 ack=1时，发送ack，ack=0，发生nack
unsigned char i2c_sim_read_byte(void)
{
	unsigned char i;
	unsigned char bit = 0;
	unsigned char data = 0;
	i2c_sim_port_setDIOMode(IS_IO_INPUT_MODE);//输入状态
	for (i = 0; i < 8; i++)
	{
		i2c_sim_port_setCLKStatus(IS_IO_LOW_LEVEL);
		i2c_sim_port_delay_nus(2);
		i2c_sim_port_setCLKStatus(IS_IO_HIG_LEVEL);
		bit = i2c_sim_port_radDIOStatus();//读出1位
		#ifdef IIC_LSB//低位在前
		data |= (bit << i);		
		#else//高位在前
		data = (data << 1) | bit;
		#endif
		i2c_sim_port_delay_nus(2);
	}
	return data;
}
